package com.yang.code_sample.performance_count.function;

import com.google.gson.Gson;
import com.yang.code_sample.performance_count.entity.RequestInfo;
import com.yang.code_sample.performance_count.entity.RequestStat;
import com.yang.code_sample.performance_count.service.MetricsStorage;
import com.yang.code_sample.performance_count.utils.Aggregator;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 控制台输出数据类
 * @Author: 杨 强
 * @CreateTime: 2022-10-13 17:27
 */
public class ConsoleReporter {
    // 数据储存接口
    private MetricsStorage metricsStorage;
    // 延迟定期执行线程池, 来达到定时的需求.
    private ScheduledExecutorService executor;

    // 依赖注入
    public ConsoleReporter(MetricsStorage metricsStorage) {
        this.metricsStorage = metricsStorage;
        this.executor = Executors.newSingleThreadScheduledExecutor();
    }

    /**
     * 统计数据触发方法
     * @param periodInSeconds 统计数据执行的间隔时间, 下面的0和periodInSeconds的意思就是, 统计执行开始时间为0, 然后间隔periodInSeconds再统计
     * @param durationInSeconds 每次统计的时间区间, 比如100秒, 就是从现在到后面100秒的数据
     */
    public void startRepeatedReport(long periodInSeconds, long durationInSeconds){
        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                // 从给定的时间区间从数据库获取数据
                long durationInMillis = durationInSeconds * 1000;
                long endTimeInMillis = System.currentTimeMillis();
                long startTimeInMillis = endTimeInMillis - durationInMillis;

                // 从具体的储存出获取数据
                Map<String, List<RequestInfo>> requestInfos =
                        metricsStorage.getRequestInfos(startTimeInMillis, endTimeInMillis);

                // 循环处理数据的聚合
                Map<String, RequestStat> stats = new HashMap<>();
                for (Map.Entry<String, List<RequestInfo>> entry : requestInfos.entrySet()) {
                    String apiName = entry.getKey();
                    List<RequestInfo> requestInfosPerApi = entry.getValue();
                    RequestStat aggregate = Aggregator.aggregate(requestInfosPerApi, durationInMillis);
                    stats.put(apiName, aggregate);
                }

                // 将数据显示到终端
                System.out.println("Time Span: [" + startTimeInMillis + ", " + endTimeInMillis + "]");
                Gson gson = new Gson();
                System.out.println(gson.toJson(stats));
            }
        }, 0, periodInSeconds, TimeUnit.SECONDS);

    }

}
